<?php
/**
 * Created by PhpStorm.
 * User: 小蛮哼哼哼
 * Email: 243194993@qq.com
 * Date: 2022/5/23
 * Time: 15:42
 * motto: 现在的努力是为了小时候吹过的牛逼！
 */

declare(strict_types=1);

namespace app\pay\controller;

use app\BaseController;
use app\common\lib\ArrClass;
use app\common\lib\Show;
use app\common\lib\Status;
use app\common\model\MallOrderRefund;
use app\pay\middleware\Auth;
use EasyWeChat\Factory;
use think\App;
use think\facade\Log;

class Payment extends BaseController
{
    protected $mini_app = null;
    protected $model = null;
    protected string $m_openid = "";

    public function __construct(App $app)
    {
        $config = [
            "app_id" => sysconfig('weixin', "wx_mini_app_id"),
            "secret" => sysconfig('weixin', 'wx_mini_secret_id'),
            'response_type' => 'array',
            'log' => [
                'level' => 'debug',
                'file' => runtime_path('easywechat') . 'wechat.log',
            ],
        ];
        $this->mini_app = Factory::miniProgram($config);
        $this->m_openid = $this->request->openid ?? "";
        parent::__construct($app);
    }

    protected $middleware = [Auth::class];

    /**
     * @return array|\think\response\Json
     */
    public function jsSdk()
    {
        $param = $this->request->sData;
        Log::info(Show::json_encode($param));
        //下单
        $url = (string)url('/pay/notify/index', [], true, true);
        $order_data = [
            'body' => $param['body'],
            'out_trade_no' => $param['out_trade_no'],
            'total_fee' => $param['total_fee'],
            'spbill_create_ip' => $param['spbill_create_ip'], // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
            'notify_url' => $url, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => $param['trade_type'], // 请对应换成你的支付方式对应的值类型
            'openid' => $param['openid'],
        ];
        //设置交易结束时间
        $time = sysconfig('shop', 'order_time');
        $time = (int)$time ?? 15;
        $second = ($time * 60) - 30;
        $end_time = time() + $second;
        $order_data['time_expire'] = date('YmdHis', $end_time);
        try {
            $result = $this->payment($order_data);
        } catch (\Exception $e) {
            return Show::json_show(Status::status_error, $e->getMessage());
        }
        return Show::json_show(Status::status_normal, "ok", Show::json_decode($result));
    }

    /**
     * 支付
     * @param array $order_data
     * @return mixed
     * @throws \ReflectionException
     * @throws \think\Exception
     */
    protected function payment(array $order_data = [])
    {
        $arr = ArrClass::payAttr();
        $obj = ArrClass::initClass('wx', $arr, [], true);
        Log::info("===============用户下单===============");
        $result = $obj->order($order_data);
        Log::info("===============用户下单返回结果===============" . Show::json_encode($result));

        if ($result['return_code'] != 'SUCCESS' || $result['result_code'] != 'SUCCESS') {
            throw new \Exception($result['err_code_des']);
        }
        Log::info("===============生成支付===============");
        return $obj->jssdk($result['prepay_id']);
    }

    public function refund()
    {
        $param = $this->request->sData;
        Log::info("==============开始退款==============");
        Log::info("退款订单:" . Show::json_encode($param));
        if (empty($param['out_trade_no'])) {
            return Show::json_show(Status::status_error, "订单号不存在");
        }
        try {
            $order = (new MallOrderRefund())->getOrderByOrderId($param['out_trade_no']);
        } catch (\Exception $e) {
            Log::error($e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
            return Show::json_show(Status::status_error, '处理失败');
        }
        if (!$order) {
            return Show::json_show(Status::status_error, "订单不存在");
        }
        $order_data = $order->toArray();
        if ($order_data['status'] != 0) {
            return Show::json_show(Status::status_normal, "等待退款");
        }
        $arr = ArrClass::payAttr();
        $obj = ArrClass::initClass('wx', $arr, [], true);
        $res = $obj->refund($order_data['order_sn'], $order_data['order_id'], intval($order_data['pay_price'] * 100), intval($order_data['refund_price'] * 100), [
            "refund_desc" => "机器故障退款"
        ]);
        Log::info("退款返回:" . Show::json_encode($res));
        if ($res['return_code'] == "SUCCESS") {
            if ($res['result_code'] == "SUCCESS") {
                $status = 2;
                $msg = "发起退款成功";
            } else {
                $status = 3;
                $msg = "发起退款失败";
            }
            $result = (new MallOrderRefund())->updateDataSave($order_data['id'], [
                "status" => $status,
                "update_time" => time(),
                "msg" => $res['err_code_des'] ?? "ok"
            ]);
            if ($result) {
                return Show::json_show(Status::status_normal, $msg);
            } else {
                return Show::json_show(Status::status_error, "修改数据库失败！发起退款成功");
            }

        } else {
            return Show::json_show(Status::status_error, $res['return_msg']);
        }
    }
}